#!/usr/bin/env python2
#-*- coding: utf-8 -*-

import sys
import functools
import traceback
import datetime


reload(sys)
sys.setdefaultencoding('utf-8')


from Ump.common import log
from Ump.common import exception
from Ump.common import config
from Ump.objs.db import models
from Ump.objs.manager_base import Manager
from Ump.objs.session_wrapper import _sw

from Ump.jsonify import data2json

LOG = log.get_log('Ump.objs.oplog.manager')


ST_DONE = 'done'
ST_FAILED = 'failed'


EVENT_MAP = {
    # GENERAL
    'create': '创建',
    'add': '添加',
    'delete': '删除',
    'update': '更新',
    'restore': '恢复删除',
    'expunge': '彻底删除',

    #HOST
    'start_node': '启动服务',
    'stop_node': '停止',

    #DISK
    'remove': '移除',
    'on': '开启',
    'off': '关闭',
    'clean_raid_miss': '清除RAID错误',

    # USER
    'login': '登录',
    'logout': '退出',
    'password': '修改密码',

    # VOLUME
    'rename': '重命名',
    'resize': '调整大小',
    'copy': '拷贝',
    'flatten': 'flatten',
    'priority': '目标分层',

    # SNAPSHOT
    'protect': '保护',
    'unprotect': '取消保护',
    'clone': '克隆',
    'rollback': '回滚',

    #
    'settask': '设置任务',
    'clear': '清除',
    'join': '加入',
    'set': '设置',
    
    'make_license': '申请激活码',
    'update_license': '导入激活码',

    #snmp
    'send': "发送测试",
    'setting': '配置',
}

RES_MAP = {
    'cluster': '集群',
    'pd': '保护域',
    'node': '节点',
    'disk': '磁盘',
    'disk_light': '磁盘灯',
    'raid': 'RAID',
    'user': '用户',
    'pool': '资源池',
    'volume': '卷',
    'vgroup': '卷组',
    'snapshot': '快照',
    'cgsnapshot': '卷组快照',
    'access_control': '访问策略',
    'snmp': 'SNMP',
    'qos': 'QoS',
    'snap_policy': '快照策略',
    'license': '注册',
    'site': '站点',
    'relationships': '复制关系',
    'settings': '监控设置',
    'statistics': '统计报表',
    'folder': '文件夹',
    'customer': 'Callhome',
    'mail': '邮件',
}

STATUS_MAP = {
    'done': '成功',
    'failed': '失败',
}

SKIP_EVENT = ['password', 'clean_raid_miss', 'start_node', 'make_license', 'update_license']


@models.add_model(models.Oplog)
class OplogManager(Manager):

    def __init__(self, resource=None, event=None, **kw):
        super(OplogManager, self).__init__()

        # control if record or not
        self.ok = True

        self.resource = resource
        self.event = event

        self.kw = kw

    def create(self, **kw):
        self.update_props(**kw)

        user_id = self._get_user_id()
        values = {
            'operation': self._get_operation(),
            'resource': self._get_resource(),
            'oplog_obj': self._get_obj(),
            'status': self._get_status(),
            'detail': '%s' % self._get_detail(),
            'user_id': user_id,
            'username': self._get_username(user_id),
        }
        res = models.Oplog(values).save()
        # print '--- oplog created', values
        return res

    def delete(self, kwargs):
        oplog_id = kwargs['ids'].split(',')
        for id in oplog_id:
            if not id:
                continue
            oplog = models.Oplog.query.get(id)
            if not oplog:
                raise exception.NotFound(oplog_id=id)
            models.Oplog.delete(oplog)

    def update_props(self, **kw):
        for k, v in kw.iteritems():
            if v:
                self.kw.update({k: v})

    def set_obj(self, obj):
        return self.update_props(oplog_obj=obj)

    def _get_username(self, user_id):
        username = None
        if user_id: 
            user = models.User.query.get(user_id)
            if user:
                username = user.name

        return username
        
    def set_user(self, username, _ss=None):
        user_id = _sw.get_user_id(username)
        return self.update_props(user_id=user_id)

    def _get_operation(self):
        if self.event in SKIP_EVENT: 
            return EVENT_MAP.get(self.event, '')
        return '%s%s' % (EVENT_MAP.get(self.event, ''), self._get_resource())

    def _get_obj(self):
        res = self.kw.get('oplog_obj', '')
        if isinstance(res, dict):
            res = data2json(res)
        return res

    def _get_user_id(self):
        res = self.kw.get('user_id')
        return res

    def _get_detail(self):
        status = self.kw.get('status', '')
        if status == ST_FAILED:
            return self.kw.get('error_msg', '')
        else:
            return self.kw.get('detail', '')

    def _get_status(self):
        status = self.kw.get('status', '')
        return STATUS_MAP.get(status, '')

    def _get_resource(self):
        return RES_MAP.get(self.resource, '')

    def delete_older(self):
        now = datetime.datetime.now()
        LOG.info('delete_older event')
        models.Oplog.is_check_deleted = 1
        oplogs = models.Oplog.query.all()
        for oplog in oplogs: 
            delta = datetime.timedelta(days=config.event_validity)
            if now - oplog.created_at < delta:
                continue

            if not oplog.deleted :
                oplog.delete()

            oplog.hard_delete()


if __name__ == '__main__':
    m = OplogManager(event='add', resource='node', status='done')
    #m.info()
